﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.IO;
using Dll;
using Dll.Model;
using System.Web.Script.Serialization;
using System.Diagnostics;

namespace WindowsFormsApplication1.HttpServer
{
    public class HttpServer
    {

        String dbPath;
        int port;
        String imageBasePath;
        ShufatiyanService ss;

        public HttpServer(String dbPath, String imageBasePath, int port)
        {
            this.dbPath = dbPath;
            this.port = port;
            this.imageBasePath = imageBasePath;
            this.ss = new ShufatiyanService(dbPath);
        }

        private void SendData<T>(T t, HttpListenerResponse response)
        {
            try
            {
                JavaScriptSerializer js = new JavaScriptSerializer();
                String result = js.Serialize(t);
                //= Utils.DataContractJsonSerialize(list).TrimEnd();
                //System.IO.File.WriteAllBytes(@"D:\test.txt",System.Text.Encoding.UTF8.GetBytes(result));
                byte[] buffer = System.Text.Encoding.UTF8.GetBytes(result);
                response.ContentLength64 = buffer.Length;
                System.IO.Stream output = response.OutputStream;
                output.Write(buffer, 0, buffer.Length);
                output.Close();
                response.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
        private void HandleContext(Object context)
        {
            HttpListenerRequest request = ((HttpListenerContext)context).Request;
            HttpListenerResponse response = ((HttpListenerContext)context).Response;
            switch (request.Url.LocalPath)
            {
                case "/category/getCategoryList":
                    List<Category> list = ss.FindCategoryList();
                    SendData(list, response);
                    break;

                case "/metaInfo/getMetaInfoList":
                    String categoryId = "";
                    int pageIndex = 0, pageSize = 0;
                    try
                    {
                        categoryId = request.QueryString.Get("categoryId");
                        pageIndex = int.Parse(request.QueryString.Get("pageIndex"));
                        pageSize = int.Parse(request.QueryString.Get("pageSize"));
                    }
                    catch (Exception)
                    {
                        response.StatusCode = 403;

                    }
                    List<MetaInfo> metaInfos = ss.FindMetaInfoListByCategoryId(categoryId, pageIndex, pageSize);
                    SendData(metaInfos, response);
                    break;
                case "/metaInfo/getMetaInfo":
                    String metaInfoId = "";
                    try
                    {
                        metaInfoId = request.QueryString.Get("metaInfoId");
                    }
                    catch (Exception)
                    {
                        response.StatusCode = 403;

                    }
                    MetaInfo meta = ss.FindMetaInfoById(metaInfoId);
                    SendData(meta, response);
                    break;
                case "/file/getFileList":
                    String metaId = "";
                    try
                    {
                        metaId = request.QueryString.Get("metaInfoId");
                    }
                    catch (Exception)
                    {
                        response.StatusCode = 403;

                    }
                    List<Dll.Model.File> files = ss.FindFileListByMetaInfoId(metaId);
                    SendData(files, response);
                    break;
                case "/file/getPreviewFile":
                    String id = "";
                    try
                    {
                        id = request.QueryString.Get("metaInfoId");
                    }
                    catch (Exception)
                    {
                        response.StatusCode = 403;

                    }
                    Dll.Model.File file = ss.FindPreviewFileByMetaInfoId(id);
                    SendData(file, response);
                    break;
                case "/getFile":

                    String img = "";
                    System.IO.Stream output1 = response.OutputStream;
                    try
                    {
                        img = request.QueryString.Get("fileName");
                        byte[] fileB = System.IO.File.ReadAllBytes(imageBasePath + "\\userdata\\works\\" + img.Substring(0, 2) + "\\" + img);
                        response.ContentLength64 = fileB.Length;
                        output1.Write(fileB, 0, fileB.Length);
                    }
                    catch (Exception)
                    {
                        response.StatusCode = 404;
                        break;

                    }
                    output1.Close();
                    response.Close();
                    break;

                    break;
                case "/getImage":
                    String fileName = "";
                    System.IO.Stream output = response.OutputStream;
                    try
                    {
                        fileName = request.QueryString.Get("fileName");
                        byte[] fileB = System.IO.File.ReadAllBytes(imageBasePath + "\\file\\" + fileName.Substring(0, 2) + "\\" + fileName);
                        int[] a ={140, 142, 87, 132, 14, 16, 158, 39, 102, 176, 182, 178, 187, 73, 20, 103, 11, 94, 126, 111, 44, 124, 151, 6, 45, 51, 77, 138, 52, 109, 196, 123, 15, 144,
    157, 75, 153, 61, 42, 41, 25, 86, 93, 134, 121, 190, 57, 59, 98, 149, 131, 117, 191, 99, 72, 4, 34, 199, 130, 143, 183, 108, 70, 197, 78, 8, 36, 89, 193, 32, 106, 3, 173,
    74, 164, 90, 167, 195, 82, 96, 46, 21, 23, 85, 54, 169, 186, 115, 166, 122, 119, 62, 101, 81, 79, 5, 159, 135, 18, 65, 198, 66, 43, 148, 104, 49, 152, 179, 165, 60, 35,
    26, 107, 0, 9, 17, 181, 76, 139, 105, 47, 163, 137, 150, 189, 184, 27, 161, 116, 95, 2, 63, 154, 84, 129, 100, 172, 141, 113, 48, 56, 145, 120, 24, 1, 133, 162, 55, 156,
    33, 37, 12, 110, 192, 68, 146, 50, 88, 114, 64, 67, 147, 7, 185, 177, 53, 80, 83, 171, 194, 29, 170, 174, 175, 71, 97, 10, 180, 118, 28, 160, 58, 40, 125, 136, 30, 188,
    22, 69, 13, 155, 128, 168, 127, 19, 38, 112, 91, 92, 31};
                        ImageDecode imageDecode = new ImageDecode(0.05, 0.002, 0.15, 0.048, a);
                        byte[] result = imageDecode.Decode(fileB);
                        response.ContentLength64 = result.Length;
                        output.Write(result, 0, result.Length);
                    }
                    catch (Exception)
                    {
                        response.StatusCode = 404;
                        break;

                    }
                    output.Close();
                    response.Close();
                    break;



                default:
                    response.StatusCode = 404;
                    byte[] error1 = System.Text.Encoding.UTF8.GetBytes("404");
                    response.ContentLength64 = error1.Length;
                    System.IO.Stream output2 = response.OutputStream;
                    output2.Write(error1, 0, error1.Length);
                    output2.Close();
                    response.Close();
                    break;
            }
        }
        private void AddUrlacl()
        {
            var netsh = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.System),
            "netsh.exe");
            string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;

            // prepare to launch netsh.exe process
            var startInfo = new ProcessStartInfo(netsh);
            startInfo.Arguments = String.Format("http add urlacl url=http://+:{0}/ user={1} listen=yes", this.port, userName);
            startInfo.UseShellExecute = true;
            startInfo.Verb = "runas";

            try
            {
                var process = Process.Start(startInfo);
                process.WaitForExit();
            }
            catch (Exception e)
            {
                Console.WriteLine("AddUrlacl 失败:" + e.Message);
            }
        }
        public void start()
        {

            HttpListener listener = new HttpListener();
            listener.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
            //netsh http add urlacl url=http://+:29107/ user=用户组或用户
            listener.Prefixes.Add(String.Format("http://+:{0}/", port));
            try
            {
                listener.Start();
            }
            catch (Exception)
            {
                AddUrlacl();
                start();
            }

            while (true)
            {
                HttpListenerContext context = listener.GetContext();
                //listener.BeginGetContext
                // HandleContext(context);
                new Thread(new ParameterizedThreadStart(this.HandleContext)).Start(context);
                //Thread.Sleep(100);
            }
        }
    }
}
